home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
DOCS
/
GENCTXT
/
CHAP6.TXT
< prev
next >
Wrap
Text File
|
1987-11-21
|
10KB
|
257 lines
Chapter 6 - Defines and Macros
DEFINES AND MACROS ARE AIDS TO CLEAR PROGRAMMING
Load and display the file named DEFINE.C for your first
look at some defines and macros. Notice lines 2 through 5
of the program, each starting with the word "#define". This
is the way all defines and macros are defined. Before the
actual compilation starts, the compiler goes through a
preprocessor pass to resolve all of the defines. In the
present case, it will find every place in the program where
the combination "START" is found and it will simply replace
it with the 0 since that is the definition. The compiler
itself will never see the word "START", so as far as the
compiler is concerned, the zeros were always there. Note
that if the string is found in a string constant or in a
comment, it will not be changed.
It should be clear to you by now that putting the word
"START" in your program instead of the numeral 0 is only a
convenience to you and actually acts like a comment since
the word "START" helps you to understand what the zero is
used for.
In the case of a very small program, such as that
before you, it doesn't really matter what you use. If,
however, you had a 2000 line program before you with 27
references to "START", it would be a completely different
matter. If you wanted to change all of the "START"s in the
program to a new number, it would be simple to change the
one #define, but difficult to find and change all of the
references to it manually, and possibly disastrous if you
missed one or two of the references.
In the same manner, the preprocessor will find all
occurrences of the word "ENDING" and change them to 9, then
the compiler will operate on the changed file with no
knowledge that "ENDING" ever existed.
It is a fairly common practice in C programming to use
all capital letters for a symbolic constant such as "START"
and "ENDING" and use all lower case letters for variable
names. You can use any method you choose since it is mostly
a matter of personal taste.
IS THIS REALLY USEFUL?
When we get to the chapters discussing input and
output, we will need an indicator to tell us when we reach
the end-of-file of an input file. Since different compilers
use different numerical values for this, although most use
either a zero or a minus 1, we will write the program with a
"define" to define the EOF used by our particular compiler.
Page 41
Chapter 6 - Defines and Macros
If at some later date, we change to a new compiler, it is a
simple matter to change this one "define" to fix the entire
program. In most C compilers, the EOF is defined in the
STDIO.H file. You can observe this for yourself by listing
this file.
WHAT IS A MACRO?
A macro is nothing more than another define, but since
it is capable of at least appearing to perform some logical
decisions or some math functions, it has a unique name.
Consider line 4 of the program on your screen for an example
of a macro. In this case, anytime the preprocessor finds
the word "MAX" followed by a group in parentheses, it
expects to find two terms in the parentheses and will do a
replacement of the terms into the second definition. Thus
the first term will replace every "A" in the second
definition and the second term will replace every "B" in the
second definition. When line 13 of the program is reached,
"index" will be substituted for every "A", and "count" will
be substituted for every "B". Once again, it must be stated
that string constants and comments will not be affected.
Remembering the cryptic construct we studied a couple of
chapters ago will reveal that "mx" will receive the maximum
value of "index" or "count". In like manner, the "MIN"
macro will result in "mn" receiving the minimum value of
"index" or "count".
The results are then printed out. There are a lot of
seemingly extra parentheses in the macro definition but they
are not extra, they are essential. We will discuss the
extra parentheses in our next program.
Compile and run DEFINE.C.
LETS LOOK AT A WRONG MACRO
Load the file named MACRO.C and display it on your
screen for a better look at a macro and its use. The second
line defines a macro named "WRONG" that appears to get the
cube of "A", and indeed it does in some cases, but it fails
miserably in others. The second macro named "CUBE" actually
does get the cube in all cases.
Consider the program itself where the CUBE of i+offset
is calculated. If i is 1, which it is the first time
through, then we will be looking for the cube of 1+5 = 6,
which will result in 216. When using "CUBE", we group the
values like this, (1+5)*(1+5)*(1+5) = 6*6*6 = 216. However,
when we use WRONG, we group them as 1+5*1+5*1+5 = 1+5+5+5 =
16 which is a wrong answer. The parentheses are therefore
Page 42
Chapter 6 - Defines and Macros
required to properly group the variables together. It
should be clear to you that either "CUBE" or "WRONG" would
arrive at a correct answer for a single term replacement
such as we did in the last program. The correct values of
the cube and the square of the numbers are printed out as
well as the wrong values for your inspection.
In line 5 we define "ADD_WRONG" according to the above
rules but we still have a problem when we try to use the
macro in line 23 and 24. In line 24 when we say we want the
program to calculate 5*ADD_WRONG(i) with i = 1, we get the
result 5*1 + 1 which evaluates to 5 + 1 or 6, and this is
most assuredly not what we had in mind. We really wanted
the result to be 5*(1 + 1) = 5*2 = 10 which is the answer we
get when we use the macro named "ADD_RIGHT(i)", because of
the extra parentheses in the definition given in line 6. A
lttle time spent studying the program and the result will be
worth your effort in understanding how to use macro's.
In order to prevent the above problems, most
experienced C programmers include parentheses around each
variable in a macro and additional parentheses around the
entire expression.
The remainder of the program is simple and will be left
to your inspection and understanding.
WHAT IS AN ENUMERATION VARIABLE?
Load and display the program named ENUM.C for an
example of how to use the "enum" type variable. Line 4
contains the first "enum" type variable named "result" which
is a variable which can take on any of the values contained
within the parentheses. Actually the variable "result" is
an "int" type variable but can be assigned any of the values
defined for it. The names within the parentheses are "int"
type constants and can be used anywhere it is legal to use
an "int" type constant. The constant "win" is assigned the
vallue of 0, "tie" the value 1, "bye" the value 2, etc.
In use, the variable "result" is used just like any
"int" variable would be used as can be seen by its use in
the program. The "enum" type of variable is intended to be
used by you, the programmer, as a coding aid since you can
use a constant named "mon" for control structures rather
than the meaningless (at least to you) value of 1. Notice
that "days" is assigned the values of days of the week in
the remainder of the program. If you were to use a "switch"
statement, it would be much more meaningful to use the
labels "sun", "mon", etc, rather than the more awkward 0, 1,
2, etc.
Page 43
Chapter 6 - Defines and Macros
PROGRAMMING EXERCISES
1. Write a program to count from 7 to -5 by counting down.
Use #define statements to define the limits. (Hint, you
will need to use a decrementing variable in the third
part of the "for" loop control.
2. Add some printf statements in MACRO.C to see the result
of the erroneous and correct addition macros.
Page 44